package mirrormonkey.state;

import mirrormonkey.state.tools.applications.ClientTestApplication;
import mirrormonkey.state.tools.applications.ServerTestApplication;
import mirrormonkey.state.tools.listeners.MakeVisibleListener;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

import com.jme3.network.HostedConnection;

public abstract class SingleClientTestProto {

	public static ServerTestApplication serverApplication;

	public static ClientTestApplication clientApplication;

	public static MakeVisibleListener visibilityListener;

	@BeforeClass
	public static void setUpClass() throws Exception {
		serverApplication = new ServerTestApplication();
		serverApplication.start();
		sleepNoInterrupt(1000);
		clientApplication = new ClientTestApplication();
		clientApplication.start();

		visibilityListener = new MakeVisibleListener();
		clientApplication.appState.listeners.addListener(visibilityListener);

		clientApplication.appState.entityProvider.parser
				.parsePresetClass(AnnotationPresets.class);
		serverApplication.appState.entityProvider.parser
				.parsePresetClass(AnnotationPresets.class);

		sleepNoInterrupt(2000);

	}

	@AfterClass
	public static void tearDownClass() throws Exception {
		sleepNoInterrupt(2000);

		clientApplication.stop();
		clientApplication = null;
		serverApplication.stop();
		serverApplication = null;
		sleepNoInterrupt(2000);
	}

	public HostedConnection getFirstConnection() {
		return serverApplication.server.getConnections().iterator().next();
	}

	public void processEvents() {
		serverApplication.appState.eventManager.processEvents();
		clientApplication.appState.eventManager.processEvents();
	}

	public static void sleepNoInterrupt(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
		}
	}

	public abstract void createBoxes();

	@Before
	public void setUp() {
		createBoxes();
		sleepNoInterrupt(100);
		processEvents();
		sleepNoInterrupt(1000);
	}

	public abstract void removeBoxes();

	@After
	public void tearDown() {
		sleepNoInterrupt(1000);
		removeBoxes();
		sleepNoInterrupt(100);
		processEvents();
		sleepNoInterrupt(100);
	}

}
